package com.rxyb.security.config;

import com.rxyb.security.filter.LoginSuccessHandler;
import com.rxyb.security.handler.AuthLimitHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * @author YJH
 * @version 1.0
 * @description Web 认证的怕配置
 * @date 2020/5/15  15:51
 */
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, jsr250Enabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 默认登录页面
        http.formLogin().loginPage("/login").permitAll();

        // 配置登录成功后默认页面
        http.formLogin().successHandler(new LoginSuccessHandler());
        // 访问权限不足页面跳转
        http.exceptionHandling().accessDeniedHandler(new AuthLimitHandler());
        // 登出登出
        http.logout().permitAll();
        // 配置登录后默认页面
        // 授权配置 调用authorizeRequests()的意思是指通过authorizeRequests()方法来开始请求权限配置，
        // anyRequest().fullyAuthenticated()是对http所有的请求必须通过授权认证才可以访问。除了fullyAuthenticated方法，
        // 还可以使用authenticated方法
        http.authorizeRequests()
                /*所有的静态资源可以访问*/
                .antMatchers("/js/**", "/css/**", "images/**").permitAll()
                /*所有以 ad 开头的资源可以访问*/
                .antMatchers("/ad/**").permitAll()
                .anyRequest().fullyAuthenticated();
    }

    /**
     * 这样在配置文件中默认用户局限性还是很大的。我们想配置多个不同的用户，每个用户拥有不同的角色，并且还有最重要的一点，用户的密码应该是加密的，不应该是明文。
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 然后配置密码加密方式，这里我们使用spring自带的推荐方式：
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("user").password(new BCryptPasswordEncoder().encode("123456")).roles("USER")
                .and()
                .withUser("admin").password(new BCryptPasswordEncoder().encode("admin")).roles("ADMIN")
                .and()
                .withUser("one").password(new BCryptPasswordEncoder().encode("one")).roles("ONE")
                .and()
                .withUser("two").password(new BCryptPasswordEncoder().encode("two")).roles("TWO")
                .and()
                .withUser("three").password(new BCryptPasswordEncoder().encode("three")).roles("THREE");
    }
}
